package com.study_security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.study_security.domain.LoginUser;
import com.study_security.domain.ResponseResult;
import com.study_security.entity.User;
import com.study_security.mapper.UserMapper;
import com.study_security.service.LoginService;
import com.study_security.utils.JwtUtil;
import com.study_security.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private EmailService emailService;

    @Override
    public ResponseResult login(User user) {
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
            Authentication authenticate = authenticationManager.authenticate(authenticationToken);

            if (Objects.isNull(authenticate)) {
                return new ResponseResult(400, "登录失败");
            }

            LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
            String userid = loginUser.getUser().getId().toString();
            String userType = loginUser.getUser().getUserType().toString();

            String jwt = JwtUtil.createJWT(userid);

            redisCache.setCacheObject("login:" + userid, loginUser);

            Map<String, String> data = new HashMap<>();
            data.put("token", jwt);
            data.put("userType", userType);
            return new ResponseResult(200, "登录成功", data);

        } catch (Exception e) {
            return new ResponseResult(500, "登录失败：" + e.getMessage());
        }
    }

    @Override
    public ResponseResult logout() {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userid = loginUser.getUser().getId();
        redisCache.deleteObject("login:" + userid);
        return new ResponseResult(200, "退出成功");
    }

    @Override
    public ResponseResult register(User user) {
        // 查询用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, user.getUserName());
        if (userMapper.selectOne(queryWrapper) != null) {
            return new ResponseResult(400, "用户名已存在");
        }

        // 查询数据库中的最大ID值
        Long maxId = userMapper.selectMaxId();
        if (maxId == null) {
            maxId = 0L;
        }
        user.setId(maxId + 1);

        // 查询验证码是否正确
        String emailKey = "verify:email:" + user.getEmail();
        String cachedCode = null;
        try {
            cachedCode = redisCache.getCacheObject(emailKey);
            if (cachedCode == null) {
                return new ResponseResult(400, "验证码无效或已过期");
            }
            if (!cachedCode.equals(user.getVerificationCode())) {
                return new ResponseResult(400, "验证码无效或已过期");
            }
        } catch (Exception e) {
            return new ResponseResult(500, "查询验证码时发生错误：" + e.getMessage());
        }

        // 设置用户其他信息
        user.setStatus("0");
        user.setCreateBy(null);
        user.setUpdateTime(new Date());
        user.setDelFlag(0);
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        // 设置用户的职务信息
        if ("1".equals(user.getUserType())) {
            user.setRole("项目负责人");
        } else if ("2".equals(user.getUserType())) {
            user.setRole(user.getRole()); // 前端、后端、运维、测试等
        }

        // 保存用户信息到数据库
        userMapper.insert(user);

        return new ResponseResult(200, "注册成功");
    }






    public ResponseResult sendVerificationCode(String email) {
        String code = String.format("%06d", new Random().nextInt(999999));
        try {
            emailService.sendVerificationCode(email, code);
            emailService.saveVerificationCode(email, code);
        } catch (Exception e) {
            return new ResponseResult(500, "验证码发送失败：" + e.getMessage());
        }
        return new ResponseResult(200, "验证码发送成功");
    }

    @Override
    public ResponseResult forgotPassword(String email, String newPassword, String verificationCode) {
        // 检查验证码是否有效
        String emailKey = "verify:email:" + email;
        String cachedCode = redisCache.getCacheObject(emailKey);
        if (cachedCode == null || !cachedCode.equals(verificationCode)) {
            return new ResponseResult(400, "验证码无效或已过期");
        }

        // 更新用户密码
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            return new ResponseResult(400, "用户不存在");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        userMapper.updateById(user);

        return new ResponseResult(200, "密码重置成功");
    }

}

